feat: powerlevel10k support and LACT R9700 tuning guide - #28
Conversation
Adds p10k package entries (yay on Arch, brew on macOS) and updates both zshrc examples to source the theme when installed, falling back to the existing vcs_info prompt when it isn't. Instant-prompt block added at the top of both files. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
CLAUDE.md: registers the graphify skill so Claude auto-invokes it on /graphify. TODO.md: documents that uv projects must use `uv run --no-sync pytest` in .claude/test-cmd to avoid uv sync reverting out-of-band package installs on every edit. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
lact_r9700_tuning.md covers ppfeaturemask prereq, apply steps, voltage offset rationale, gaming vs inference profiles, and stability testing. lact_r9700.yaml is a drop-in LACT config with -80mV offset, 210W cap, and a 5-point junction fan curve tuned for RDNA4. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Arch-only for now; pairs with the new lact_r9700_tuning.md guide. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Ramps from 30% at 50C to 60% at 75C and 80% at 90C junction. Previous curve maxed at 40% at 90C — too conservative for sustained inference load. Targets junction under ~80C with some noise tradeoff. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Consolidates bottom of curve to one idle point (35C/25%) freeing up slots for 70/75/80/90 steps. Gradual 7-8% increments per step keep fan speed changes subtle while maintaining cooling past the knee. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…ssive Averages speeds between the conservative original (max 40% at 90C) and the aggressive version (max 80% at 90C). Result: quiet below 70C, gentle 5C-step ramp to 60% at 90C junction. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…sk fix - Add gpu_od health check as first step — some R9700 boards (ASUS Turbo vBIOS 115-G287BP00-100) have SMU v46/v50 mismatch that makes fan control a no-op; fan curve is silently ignored on affected units - Fix ppfeaturemask guidance: must be kernel cmdline, not modprobe.d; driver silently strips OD feature bit (0x4000) from modprobe config - Add sysfs fallback commands for voltage + power cap when LACT can't reach fan/clock registers - Add 315W / -75mV performance profile from amd-r9700-vllm-toolboxes - Add lact-cli reference (list-gpus, info only — all tuning is config-file) - Update references with ROCm issues 6078/6101 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…MU bug - Replace hardcoded card0 with dynamic AMD card lookup (card number varies) - Correct stock power cap: 300W (confirmed), range 210-300W (not ~260W) - Voltage offset is also blocked by SMU bug, not just fan control — both pp_od_clk_voltage and gpu_od are absent on affected units - Cap performance profile at 300W max (not 315W which exceeds hw limit) - Sysfs fallback section now accurately reflects power-cap-only capability on SMU bug units, with conditional voltage offset block for unaffected units Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
R9700 AI Pro — LACT findings from live testingDocumenting what we've learned from actually running this on the hardware (Sapphire R9700 AI Pro, headless CachyOS). Hardware confirmed
Active bugs (as of May 2026)1. SMU interface version mismatch — partially brokenDriver expects SMU v46 ( On this Sapphire unit the impact is partial — worse on the ASUS Turbo variant:
ROCm tracking issue: ROCm/ROCm#6101 (open, 54 comments) 2.
|
Captured from Sapphire R9700 AI Pro on CachyOS 2026-05-29. Baseline to restore from if tuning goes wrong. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Power cap impact by workload typeQuick reference for how the 210W vs 300W cap affects different scenarios on the R9700 AI Pro. The key factor is what's bottlenecking the workload — compute (shader throughput, clock-sensitive) or memory bandwidth (VRAM bandwidth, largely clock-insensitive). Inference
Decode fetches the full model weights from VRAM each token. At 644 GB/s the shaders sit mostly idle waiting on memory — capping clocks barely moves tokens/sec. For typical chat (short prompts, long outputs) the cap is nearly invisible. For long-context or RAG workloads where prefill dominates, you'll feel the ~15% TTFT hit. Training / SFTMost impacted. Forward pass, backward pass, and gradient computation are all sustained matrix ops that max out shader throughput. The GPU hits the power cap immediately and throttles clocks to stay there. Estimated impact: ~15–25% slower depending on batch size and model architecture. Larger batches are more compute-efficient and feel the cap more; tiny batches less so. For SFT: run at 300W. GamingMost sensitive. Rasterization and shading are sustained compute-bound by design — the GPU is meant to run at max clocks the whole time. 210W vs 300W is a 30% power reduction → roughly 15–25% lower FPS in sustained heavy scenes (open world, ray tracing, dense geometry). Lighter scenes that don't push TDP won't be affected. Summary
Once the SMU bug is fixed and voltage offset becomes available, -75 to -80mV will recover most of the performance lost to the power cap — you get ~same compute at lower thermals rather than just trading performance for quiet. |
…pport Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Adds the generated p10k.zsh to the repo and wires it into setup.sh with the same backup-on-diff pattern used for zshrc/tmux/ghostty. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
shellcheck picks up .zsh files and can't parse zsh-specific syntax. Renaming to .example matches the zshrc.example convention already used in the repo for dotfile templates. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…ified stack (#36) Merge origin/main (PRs #28 powerlevel10k/LACT, #35 railguard fixes, #38 claude-hud) into the unification branch. The two PRs that touched the legacy setup stack landed while this branch converted it to shims, so their features are ported into the unified system as part of the conflict resolution: - packages.json gains zsh-theme-powerlevel10k (arch/yay, high) and lact (arch/yay, medium) — the entries main added to the now-deleted linux-desktop/linux_desktop_packages.json. - The shared desktop flow (lib/core.sh) deploys ~/.p10k.zsh from linux-desktop/p10k.zsh.example via deploy_config — the step main added to the legacy linux-desktop/setup.sh, which stays a shim. - Everything else from main merges clean: zshrc.examples, ghostty font, p10k.zsh.example, LACT configs/docs, railguard and claude-hud config. Gate: per-platform full-flag dry-run diffed against the pre-merge snapshot — macOS and server unchanged (timestamp only); ubuntu/arch show exactly the intended additions (p10k deploy, the two arch packages, and the zshrc update caused by main's new zshrc.example content). dryrun-smoke 4/4; shellcheck + jq clean. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Summary
zsh-theme-powerlevel10kpackage (Arch) andpowerlevel10kbrew formula (macOS); updates bothzshrc.examplefiles to source p10k when installed, falling back to the existingvcs_infoprompt when it isn'tlactpackage entry (Arch); addslact_r9700_tuning.mdguide andlact_r9700.yamlconfig template; addslact_default_backup.yamlstock config snapshot from live hardwareCLAUDE.md; documentsuv run --no-sync pytestrequirement inTODO.mdLACT notes (R9700 AI Pro, live-tested on Sapphire/CachyOS)
Known active bugs (May 2026):
gpu_odandpp_od_clk_voltageabsent on affected hardware; AMD fix targeting ROCm 7.13 (ROCm #6101)ppfeaturemaskmust be set via kernel boot parameter — modprobe silently strips the OD feature bit with no log warningMinor patches applied during testing:
card0→ dynamic AMD card lookup (card number varies by system)lact-cliheadless reference and sysfs power-cap-only fallback for affected unitsTest plan
p10k configureon fresh Arch install produces a working prompt; fallbackvcs_infoprompt works when p10k absentlactinstalls cleanly viayayon CachyOSlact cli power-limit getshows 210–300W rangelact cli statsreports non-zero GFX clocks; fan curve and voltage offset take effect without config changes🤖 Generated with Claude Code